# *-*- coding:utf-8 -*-
# @Author  : Eliza
# @Time    : 2021/7/18 14:53
# @Software : RubyMine

# 迭代器
arr01 = [1, 23, 54]
arr01.each { |value| p value } #优先级较高

arr01.each do |value|
  p value
end
# 块 ( block )： Ruby 解析器识别出一个块时，它将与调用的方法相关联，并逐字地替换方法中的 yield
# yield关键字在ruby中表示调用块。
# yield的出现应该满足两个条件：一个方法的定义，在方法内部有yield的出现；
# 一个是方法的调用处，在方法的调用处会有程序块的出现。

def one_yield
  yield
end

def multiple_yields
  yield
  yield
end

#块 作为参数传进去，出现yield的地方 会自动执行块 中的代码
one_yield { puts "one yield" }
multiple_yields { puts "multiple yields" }

puts "---------"

def optional_block
  yield if block_given? #如果给了块
end

optional_block
optional_block { puts 'optional block' }
puts "---------"
# 给 yield 关键字传递参数
def yield_with_arguments
  hello = 'Hello'
  world = 'World!'
  yield(hello, world)
end

yield_with_arguments { puts "-" }
yield_with_arguments { |key, value| puts "#{key},#{value}" }

puts "---------"
# 只需将 yield 的返回值赋给变量，就可以获得块的返回值

def yield_with_return_value
  hello_world = yield
  puts hello_world + ":sss"
end

yield_with_return_value { "ok" } #ok:sss
puts "---------"

def total(from, to)
  result = 0
  from.upto(to) do |num|
    # 让块变得可选 ( option )，Kernel#block_given?
    if block_given?
      result += yield(num) #调用块
    else
      result += num
    end
  end
  return result
end

p total(1, 10) # ，1到10的和 55
p total(1, 10) { |num| num **2 } #从1到10的2次幂的和 385